package com.cjd.common.okhttp3

import android.text.TextUtils
import com.cjd.common.event.FileDownloadEvent
import com.cjd.common.utils.ActivityLifecycleCallbacksUtil
import com.cjd.common.utils.LogUtils
import com.cjd.common.utils.OkHttpUtils
import okhttp3.ResponseBody
import org.greenrobot.eventbus.EventBus
import retrofit2.Converter
import java.io.File
import java.io.FileOutputStream
import java.io.InputStream

/**
 * @Author chenjidong
 * @email 374122600@qq.com
 * created 2019/12/12
 * description
 */
class FileResponseConverter(annotations: Array<Annotation>) : Converter<ResponseBody, File> {
    lateinit var fileName: String
    lateinit var interruptKey: String

    init {
        for (annotation in annotations) {
            if (annotation is FileConverter) {
                fileName = annotation.fileName
                interruptKey = annotation.interruptKey
            }
        }
    }

    override fun convert(value: ResponseBody): File? {
        val suffix = value.contentType()?.subtype()
        val path = if (TextUtils.isEmpty(fileName)) {
            OkHttpUtils.CACHE_DIRECTORY + File.separator + "${System.currentTimeMillis()}." + suffix
        } else
            OkHttpUtils.CACHE_DIRECTORY + File.separator + fileName

        var inputStream: InputStream? = null
        var fileOutputStream: FileOutputStream? = null
        val newFile = File(path)
        try {
            val totalLength = value.contentLength()
            var writeLength = 0L
            inputStream = value.byteStream()

            if (newFile.parentFile == null || !newFile.parentFile.exists()) {
                newFile.parentFile.mkdirs()
            }
            fileOutputStream = FileOutputStream(newFile)

            val data = ByteArray(4096)

            var length = inputStream.read(data)
            var nowInterrupt = isInterruptWrite(interruptKey)
            while (length != -1) {
                nowInterrupt = isInterruptWrite(interruptKey)
                if (nowInterrupt)
                    break
                fileOutputStream.write(data, 0, length)
                writeLength += length

                var percent: Int = (100 * writeLength / totalLength).toInt()
                LogUtils.d("--->$percent")
                if (percent >= 99)
                    percent = 99
                sendEvent(interruptKey, path, percent)
                length = inputStream.read(data)
            }
            if (nowInterrupt) {
                newFile.delete()
            } else {
                fileOutputStream.flush()
                sendEvent(interruptKey, path, 100)
            }

        } catch (e: Exception) {
            LogUtils.e(e)
            newFile?.delete()
            sendEvent(interruptKey, path, -1)

            return null
        } finally {
            try {
                inputStream?.close()
                fileOutputStream?.close()
                value.close()
            } catch (e: Exception) {
                LogUtils.e(e)
                newFile?.delete()
                sendEvent(interruptKey, path, -2)
                return null
            }
        }
        return newFile
    }

    private fun isInterruptWrite(interruptKey: String): Boolean {
        return ActivityLifecycleCallbacksUtil.isNowInterrupt(interruptKey)
    }


    private fun sendEvent(interruptName: String, path: String, percent: Int) {
        EventBus.getDefault().post(FileDownloadEvent(interruptName, path, percent))
    }

}